package keeto.com.vn.classified.utils;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;

import keeto.com.vn.classified.config.IConstant;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.media.ExifInterface;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.provider.MediaStore.MediaColumns;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;


/**
 * @category 用于处理图片的工具类
 * */
public class ImageUtilities {

	private static final String TAG = "ImageUtilities";
	private static final Object lock = new Object();

	public static String FILE_ABOUT_TO_DECODE = "";

	// Rotates the bitmap by the specified degree.
	// If a new bitmap is created, the original bitmap is recycled.
	public static Bitmap rotate(Bitmap b, int degrees, Matrix m) {
		if (degrees != 0 && b != null) {
			if (m == null) {
				m = new Matrix();
			}
			m.setRotate(degrees, (float) b.getWidth() / 2,
					(float) b.getHeight() / 2);
			try {
				Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
						b.getHeight(), m, true);
				if (b != b2) {
					b.recycle();
					b = b2;
				}
			} catch (OutOfMemoryError ex) {
				// We have no memory to rotate. Return the original bitmap.
				Log.e(TAG, "Got oom exception ", ex);
			}
		}
		return b;
	}

	/**
	 * 
	 * @param srcPath
	 * @param destPath
	 * @param m
	 * @return
	 * @throws IOException
	 */
	public static void autoRotateAndSave2DestPath(String srcPath,
			String destPath, int maxWidth, int maxHeight) throws IOException {

		ExifInterface exif = new ExifInterface(srcPath);
		int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION,
				ExifInterface.ORIENTATION_NORMAL);
		int degrees = 0;
		switch (orientation) {
		case ExifInterface.ORIENTATION_ROTATE_90:
			degrees = 90;
			break;
		case ExifInterface.ORIENTATION_ROTATE_180:
			degrees = 180;
			break;
		case ExifInterface.ORIENTATION_ROTATE_270:
			degrees = 270;
			break;
		}

		Bitmap b = ImageUtilities.getBitmapThumbnailFromFile(srcPath, maxWidth,
				maxHeight);

		Matrix m = new Matrix();

		// get rotate bitmap
		Bitmap newBitmap = rotate(b, degrees, m);

		// save to original path
		saveToPath(newBitmap, destPath);
	}

	/**
	 * @category 将位图转换成Drawable
	 * @param bitmap
	 *            位图
	 * @return Drawable 对象 如果传入的bitmap为null 返回null
	 * */
	public static Drawable bitmap2Drawable(Bitmap bitmap) {
		if (null == bitmap)
			return null;
		BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
		return bitmapDrawable;
	}

	/**
	 * @category 将Drawable转换成位图
	 * @param drawable
	 * @return Bitmap 对象
	 * */
	public static Bitmap drawable2Bitmap(Drawable drawable) {
		Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
		return bitmap;
	}

	/**
	 * @category 将bitmap 转换成byte数组
	 * @param bitmap
	 *            位图
	 * @param quality
	 *            质量 0到100
	 * @param format
	 *            转换的格式 {@link Bitmap.CompressFormat}
	 * @throws IOException
	 * */
	public static byte[] bitmap2ByteArray(final Bitmap bitmap, int quality,
			Bitmap.CompressFormat format) throws IOException {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		bitmap.compress(format, quality, baos);
		byte[] bs = baos.toByteArray();
		baos.close();
		return bs;
	}

	/**
	 * @category 将bitmap转换成byte数组
	 * @param imageFile
	 *            位图文件
	 * @param quality
	 *            质量 0到100
	 * @param format
	 *            转换的格式 {@link Bitmap.CompressFormat}
	 * @throws IOException
	 * */
	public static byte[] ImageFile2ByteArray(File imageFile, int quality,
			Bitmap.CompressFormat format) throws IOException {
		FileInputStream fis = new FileInputStream(imageFile);
		Bitmap bi = BitmapFactory.decodeStream(fis);
		fis.close();
		return ImageUtilities.bitmap2ByteArray(bi, quality, format);
	}

	/**
	 */
	public static Drawable byteArray2Drawable(byte[] source, int newWidth,
			int newHeight) {
		Bitmap bitmap = byteArray2Bimap(source);
		Bitmap newBmp = getResizedBitmapFromBitmap(bitmap, newWidth, newHeight);
		return new BitmapDrawable(newBmp);
	}

	// /**
	// *
	// *
	// * @throws FileNotFoundException
	// * @category 将传入的路径对应的文件读成Bitmap
	// * @param newSize
	// * 图片缩放的新尺寸
	// * */
	// public static Bitmap thumbnailBitmap(String imagePath, int newSize)
	// throws FileNotFoundException {
	//
	// // Decode image size
	// File f = new File(imagePath);
	// BitmapFactory.Options o = new BitmapFactory.Options();
	// o.inJustDecodeBounds = true;
	//
	// BitmapFactory.decodeStream(new FileInputStream(f), null, o);
	// // The new size we want to scale to
	// final int REQUIRED_SIZE = newSize;
	// // Find the correct scale value. It should be the power of 2.
	// int width_tmp = o.outWidth, height_tmp = o.outHeight;
	// int scale = 1;
	// while (true) {
	// if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE)
	// break;
	// width_tmp /= 2;
	// height_tmp /= 2;
	// scale *= 2;
	// }
	//
	// // Decode with inSampleSize
	// BitmapFactory.Options o2 = new BitmapFactory.Options();
	// o2.inSampleSize = scale;
	// return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
	//
	// }

	/**
	 * @category 存储Bitmap
	 * @param bitmap
	 *            要存储的Bitmap对象
	 * @param filePathOut
	 *            存储目标文件路径
	 * @param quality
	 *            存储的质量 数值为:1到100
	 * @throws IOException
	 * */
	public static void saveMyBitmap(Bitmap bitmap, String filePathOut,
			int quality) throws IOException {
		File f = new File(filePathOut);
		f.createNewFile();
		FileOutputStream fOut = null;
		fOut = new FileOutputStream(f);
		bitmap.compress(Bitmap.CompressFormat.JPEG, quality, fOut);
		fOut.flush();
		fOut.close();
	}

	/**
	 * @category 生成指定高和宽的缩略图
	 * @param bitmapPath
	 *            位图路径
	 * @param width
	 *            缩略宽度
	 * @param height
	 *            缩略高度
	 * @return Bitmap 缩放后的对象
	 * */
	public static Bitmap getBitmapThumbnailFromFile(final String bitmapPath,
			int width, int height) {

		FILE_ABOUT_TO_DECODE = bitmapPath;

		BitmapFactory.Options opts = new BitmapFactory.Options();

		FILE_ABOUT_TO_DECODE = bitmapPath;

		// 设置该属性才能得到原始的宽和高
		opts.inJustDecodeBounds = true;

		Log.d(TAG, "getBitmapThumbnailFromFile" + bitmapPath);

		BitmapFactory.decodeFile(bitmapPath, opts);

		opts.inSampleSize = computeSampleSize(opts, -1, width * height);
		opts.inJustDecodeBounds = false;

		Bitmap bmp = null;
		try {

			bmp = BitmapFactory.decodeFile(bitmapPath, opts);

		} catch (OutOfMemoryError err) {
			if (bmp != null) {
				bmp.recycle();
			}
		}
		return bmp;

	}

	/**
	 * @category 生成指定高和宽的缩略图 并保存
	 * @param bitmapPath
	 *            位图路径
	 * @param width
	 *            缩略宽度
	 * @param height
	 *            缩略高度
	 * @param destBitmapPath
	 *            目标路径
	 * @return void
	 * */
	public static void thumbnailBitmapAndSave(final String sourceBitmapPath,
			int width, int height, final String destBitmapPath)
			throws IOException {

		Bitmap bitmap = getBitmapThumbnailFromFile(sourceBitmapPath, width,
				height);
		saveToPath(bitmap, destBitmapPath);
	}

	public static void thumbnailBitmapAndOverwriteOriginalFile(
			final String sourceBitmapPath, int width, int height) {
		Bitmap bitmap = getBitmapThumbnailFromFile(sourceBitmapPath, width,
				height);
		saveToPath(bitmap, sourceBitmapPath);
	}

	public static String thumbnailBitmapAndSaveTempFile(
			final String sourceBitmapPath, int width, int height) {
		// Bitmap bitmap = getBitmapThumbnailFromFile(sourceBitmapPath, width,
		// height);
		int start = sourceBitmapPath.lastIndexOf("/");
		String name = sourceBitmapPath.substring(start + 1);
		String tempDir = StringUtil.getImgTempFileDir() + name;
		thumbAndSaveToPath(
				getBitmapThumbnailFromFile(sourceBitmapPath, width, height),
				tempDir);
		return tempDir;
	}

	/**
	 * @category 该代码出自SDK
	 * */
	private static int computeSampleSize(BitmapFactory.Options options,

	int minSideLength, int maxNumOfPixels) {

		double w = options.outWidth;

		double h = options.outHeight;

		int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math
				.sqrt(w * h / maxNumOfPixels));

		int upperBound = (minSideLength == -1) ? 128 : (int) Math.min(
				Math.floor(w / minSideLength),

				Math.floor(h / minSideLength));

		if (upperBound < lowerBound) {

			// return the larger one when there is no overlapping zone.

			return lowerBound;

		}

		if ((maxNumOfPixels == -1) &&

		(minSideLength == -1)) {

			return 1;

		} else if (minSideLength == -1) {

			return lowerBound;

		} else {

			return upperBound;

		}

	}

	/**
	 * @category 根据URI获取多媒体路径
	 * @param uri
	 *            媒体的uri路径
	 * @param activity
	 *            视图类对象
	 * @return String 多媒体路径
	 * */
	public static String getMediaPath(Uri uri, Activity activity) {

		String[] projection = { MediaColumns.DATA };

		Cursor cursor = activity
				.managedQuery(uri, projection, null, null, null);

		activity.startManagingCursor(cursor);

		int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA);

		cursor.moveToFirst();

		return cursor.getString(column_index);

	}

	/**
	 * @category 获取位图占用的内存大小
	 * @param bitmap
	 *            位图
	 * @param quality
	 *            质量 0到100
	 * @param format
	 *            转换的格式 {@link Bitmap.CompressFormat}
	 * @return 大小(单位byte)
	 * @throws IOException
	 * */
	public static int getBitMapSize(Bitmap bitmap, int quality,
			Bitmap.CompressFormat format) throws IOException {
		int size = 0;
		size = bitmap2ByteArray(bitmap, quality, format).length;
		return size;
	}

	/**
	 * @category 获取位图占用的内存大小
	 * @param drawable
	 *            位图
	 * @param quality
	 *            质量 0到100
	 * @param format
	 *            转换的格式
	 * @return 大小(单位byte)
	 * @throws IOException
	 * */
	public static int getBitMapSize(Drawable drawable, int quality,
			Bitmap.CompressFormat format) throws IOException {
		int size = 0;
		Bitmap bitmap = drawable2Bitmap(drawable);
		size = bitmap2ByteArray(bitmap, quality, format).length;
		return size;
	}

	/** 原本在IconUtil中的 **/

//	private static boolean D = IM.DEBUG;
//
//	private static int idOnline = R.drawable.presence_online;
//	private static int idOffline = R.drawable.presence_offline;
//	private static int idAway = R.drawable.presence_away;
//	private static int idBusy = R.drawable.presence_busy;
//	private static int idXA = R.drawable.presence_away;
//	private static int idHide = R.drawable.presence_hide;
//
//	private static int idBuiltinDefault = R.drawable.ic_buildin_default_head;
//	private static int idGatewayDefault = R.drawable.ic_gateway_default_head;
//
//	private static int idFileTypeAudio = R.drawable.file_type_audio;
//	private static int idFileTypeImage = R.drawable.file_type_image;
//	private static int idFileTypeDoc = R.drawable.file_type_doc;
//	private static int idFileTypePdf = R.drawable.file_type_pdf;
//	private static int idFileTypeRar = R.drawable.file_type_rar;
//	private static int idFileTypeVideo = R.drawable.file_type_video;
//	private static int idFileTypeAndroid = R.drawable.file_type_android;
//	private static int idFileTypeGeo = R.drawable.default_map;
//	private static int idFileUnknown = R.drawable.file_type_unknown;

	/*
	 * key sets
	 */
	private static String[] mPresenceKey = new String[] { IConstant.ONLINE, // onLine
			IConstant.XA, // idle for 30 minutes
			IConstant.BUSY, // busy
			IConstant.AWAY, // away
			IConstant.HIDE, // hide see as offline in other client.
			IConstant.OFFLINE };// offline

//	public static int getFileTypeImageByExtension(int mimeType) {
//
//		switch (mimeType) {
//		case IMIMEType.TYPE_AUDIO:
//			return idFileTypeAudio;
//		case IMIMEType.TYPE_IMAGE:
//			return idFileTypeImage;
//		case IMIMEType.TYPE_GEO:
//			return idFileTypeGeo;
//		case IMIMEType.TYPE_PACKAGE:
//			return idFileTypeRar;
//		case IMIMEType.TYPE_WEB:
//		case IMIMEType.TYPE_TEXT:
//			return idFileTypeDoc;
//		case IMIMEType.TYPE_VIDEO:
//			return idFileTypeVideo;
//		case IMIMEType.TYPE_APK:
//			return idFileTypeAndroid;
//		case IMIMEType.TYPE_FILE:
//		case IMIMEType.TYPE_UNKOWN:
//			return idFileUnknown;
//		default:
//			return idFileUnknown;
//		}
//	}

	/**
	 * 
	 * @param thumbnail
	 * @param mimeType
	 * @param context
	 * @param thumbnailWidth
	 * @param thumbnailHeight
	 * @return
	 */
//	public static Drawable getThumbnailFromResAndMIME(String thumbnail,
//			int mimeType, Context context, int thumbnailWidth,
//			int thumbnailHeight) {
//		Drawable des = null;
//		if (!TextUtils.isEmpty(thumbnail)) {
//			byte[] array = string64ToByteArray(thumbnail);
//			Bitmap bitmap = BitmapFactory.decodeByteArray(array, 0,
//					array.length);
//
//			Bitmap resizedBmp = getResizedBitmapFromBitmap(bitmap,
//					thumbnailWidth, thumbnailHeight);
//
//			if (resizedBmp == null) {
//
//				des = context.getResources().getDrawable(
//						getFileTypeImageByExtension(mimeType));
//				return des;
//
//			} else {
//
//				BitmapDrawable drawable = new BitmapDrawable(
//						context.getResources(), resizedBmp);
//
//				return drawable;
//			}
//		} else {
//			des = context.getResources().getDrawable(
//					getFileTypeImageByExtension(mimeType));
//			return des;
//		}
//	}

	/**
	 * @return drawable resource id according to presence.
	 */
//	public static int getImageResourceIdByPresence(String presence,
//			boolean isConnected) {
//		if (isConnected) {
//			if (presence.equals(IConstant.ONLINE)) {
//				return idOnline;
//			} else if (presence.equals(IConstant.OFFLINE)) {
//				return idOffline;
//			} else if (presence.equals(IConstant.AWAY)) {
//				return idAway;
//			} else if (presence.equals(IConstant.BUSY)) {
//				return idBusy;
//			} else if (presence.equals(IConstant.XA)) {
//				return idXA;
//			} else if (presence.equals(IConstant.HIDE)) {
//				return idHide;
//			} else {
//				return idOffline;
//			}
//		} else {
//			return idOffline;
//		}
//	}

	/**
	 * 
	 * @param isBuiltin
	 * @return
	 */
//	public static int getRosterIconByType(int isBuiltin) {
//		if (isBuiltin == IConstant.TYPE_BUITIN) {
//			return idBuiltinDefault;
//		} else {
//			return idGatewayDefault;
//		}
//	}

	/**
	 * 
	 * @param b
	 * @return
	 */
	public static Bitmap byteArray2Bimap(byte[] b) {
		synchronized (lock) {
			try {
				if (b != null && b.length > 0) {
					Bitmap bm = BitmapFactory.decodeByteArray(b, 0, b.length);
					return bm;
				} else {
					return null;
				}
			} catch (Exception e) {
				Log.e("Icon Utils", e.toString());
			}
			return null;
		}
	}

	/**
	 * 
	 * @param b
	 * @return
	 */
	public static Bitmap byteArray2BimapAndGrey(byte[] b) {

		if (b == null)
			return null;

		try {
			if (b.length > 0) {
				Bitmap bm = BitmapFactory.decodeByteArray(b, 0, b.length);
				return toGrayscale(bm);
			} else {
				return null;
			}
		} catch (Exception e) {
			Log.e("Icon Utils", e.toString());
		}
		return null;
	}

	/**
	 * Convert a RGB bitmap to Gray Scale bitmap and keep the transparency
	 * 
	 * @param bmpOriginal
	 *            - RGB bitmap
	 * @return gray scale bitmap
	 */
	public static Bitmap toGrayscale(Bitmap bmpOriginal) {

		if (bmpOriginal == null) {
			return null;
		}

		int width, height;
		height = bmpOriginal.getHeight();
		width = bmpOriginal.getWidth();

		Bitmap bmpGrayscale = Bitmap.createBitmap(width, height,
				Bitmap.Config.ARGB_4444);
		Canvas c = new Canvas(bmpGrayscale);
		Paint paint = new Paint();
		ColorMatrix cm = new ColorMatrix();
		// Set the matrix to affect the saturation of colors. A value of 0 maps
		// the color to gray-scale. 1 is identity.
		cm.setSaturation(0);
		ColorMatrixColorFilter f = new ColorMatrixColorFilter(cm);
		paint.setColorFilter(f);
		c.drawBitmap(bmpOriginal, 0, 0, paint);
		return bmpGrayscale;
	}

	/**
	 * Convert a bitmap to round corner
	 * 
	 * @param bitmap
	 *            - original bitmap source
	 * @param pixels
	 *            - corner radius
	 * @return round corner bitmap
	 * 
	 */
	public static Bitmap toRoundCorner(Bitmap bitmap, int pixels) {

		Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
				bitmap.getHeight(), Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242; // near to black
		final Paint paint = new Paint();
		final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		final RectF rectF = new RectF(rect);
		final float roundPx = pixels;

		// 消除锯齿
		paint.setAntiAlias(true);
		// init the canvas to black
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return output;
	}

	/**
	 * 
	 * Get a short cut drawable from byte array with max thumbnail size.
	 * 
	 * @param src
	 *            - byte array of image
	 * @param thumbnailWidth
	 *            - max thumbnail width
	 * @param thumbnailHeight
	 *            - max thumbnail height
	 * @param context
	 *            - context
	 * @return drawable of thumbnail
	 */
	// public static Drawable thumbnailBitmap(byte[] src, int thumbnailWidth,
	// int thumbnailHeight, Context context) {
	// BitmapDrawable drawable = null;
	// Bitmap bitmap = thumbnailBitmap(src, thumbnailWidth, thumbnailHeight);
	// if (bitmap != null) {
	// drawable = new BitmapDrawable(context.getResources(), bitmap);
	// }
	// return drawable;
	// }

	// /**
	// *
	// * @param imagePath
	// * @param maxWidth
	// * @param maxHeight
	// */
	// public static void compressFile(String imagePath, int maxWidth,
	// int maxHeight) {
	// int halfMaxWidth = maxWidth / 2;
	// int halfMaxHeight = maxHeight / 2;
	//
	// Bitmap bmp = decodeFile(imagePath, halfMaxWidth, halfMaxHeight, false);
	// FileOutputStream out = null;
	// try {
	//
	// out = new FileOutputStream(imagePath);
	//
	// } catch (FileNotFoundException e) {
	// e.printStackTrace();
	// }
	// bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
	//
	// }

	/**
	 * decode to bitmap from file system.
	 * 
	 * @param url
	 * @return bitmap
	 */
	public static Bitmap getBitmapFromFile(String url) {
		synchronized (lock) {
			FILE_ABOUT_TO_DECODE = url;
			return BitmapFactory.decodeFile(url);
		}

	}

	// /**
	// *
	// * @param src
	// * @param targetWidth
	// * @param targetHeight
	// * @return
	// */
	// public static Bitmap thumbnailBitmap(byte[] src, int targetWidth,
	// int targetHeight) {
	//
	// BitmapFactory.Options options = new BitmapFactory.Options();
	//
	// options.inJustDecodeBounds = true;
	// options.outWidth = 0;
	// options.outHeight = 0;
	// options.inSampleSize = 1;
	//
	// // 获取参数
	// BitmapFactory.decodeByteArray(src, 0, src.length, options);
	//
	// if (options.outWidth > 0 && options.outHeight > 0) {
	// int widthFactor = (options.outWidth + targetWidth - 1)
	// / targetWidth;
	// int heightFactor = (options.outHeight + targetHeight - 1)
	// / targetHeight;
	//
	// widthFactor = Math.max(widthFactor, heightFactor);
	// widthFactor = Math.max(widthFactor, 1);
	//
	// // Now turn it into a power of two.
	// if (widthFactor > 1) {
	// if ((widthFactor & (widthFactor - 1)) != 0) {
	// while ((widthFactor & (widthFactor - 1)) != 0) {
	// widthFactor &= widthFactor - 1;
	// }
	// widthFactor <<= 1;
	// }
	// }
	// options.inSampleSize = widthFactor;
	// options.inJustDecodeBounds = false;
	// Bitmap bitmap = BitmapFactory.decodeByteArray(src, 0, src.length,
	// options);
	// return bitmap;
	// }
	// return null;
	// }

	// /**
	// *
	// * @param filePath
	// * @param fileName
	// * @throws FileNotFoundException
	// */
	// public static void resizeBitmap(String filePath, String fileName)
	// throws FileNotFoundException {
	// byte[] body = null;
	// File file = new File(filePath, fileName);
	// FileInputStream fis = new FileInputStream(file);
	// Bitmap bi = BitmapFactory.decodeStream(fis);
	// ByteArrayOutputStream baos = new ByteArrayOutputStream();
	// bi.compress(Bitmap.CompressFormat.JPEG, 60, baos);
	// body = baos.toByteArray();
	// Bitmap bitmap = thumbnailBitmap(body, 100, 100);
	// saveToPath(bitmap, filePath);
	// }
	//
	// /**
	// *
	// * @param filePath
	// * @throws FileNotFoundException
	// */
	// public static void resizeBitmap(String filePath)
	// throws FileNotFoundException {
	//
	// byte[] body = null;
	//
	// FileInputStream fis = new FileInputStream(filePath);
	// Bitmap bi = BitmapFactory.decodeStream(fis);
	// ByteArrayOutputStream baos = new ByteArrayOutputStream();
	// bi.compress(Bitmap.CompressFormat.JPEG, 60, baos);
	// body = baos.toByteArray();
	// Bitmap bitmap = thumbnailBitmap(body, 100, 100);
	// saveToPath(bitmap, filePath);
	//
	// }
	//
	// /**
	// *
	// * @param imagebody
	// * @param filePath
	// * @throws FileNotFoundException
	// */
	// public static void resizeBitmap(byte[] imagebody, String filePath)
	// throws FileNotFoundException {
	//
	// Bitmap bitmap = thumbnailBitmap(imagebody, 100, 100);
	// saveToPath(bitmap, filePath);
	//
	// }

	/**
	 * @category 保存到指定的路径
	 * @param bm
	 *            要保存的位图
	 * @param filePath
	 *            要保存的路径
	 * */
	public static void saveToPath(Bitmap bm, String filePath) {

		OutputStream outStream = null;
		File file = new File(filePath);
		try {
			outStream = new FileOutputStream(file);
			// save original quality, Facebook, SNS, Club photo all rely on the
			// following line, need refactoring
			bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
			outStream.flush();
			outStream.close();

			Log.i("Hub", "OK, Image Saved to Path");
			Log.i("Hub",
					"height = " + bm.getHeight() + ", width = " + bm.getWidth());

		} catch (FileNotFoundException e) {

			e.printStackTrace();
			Log.i("Hub", "FileNotFoundException: " + e.toString());

		} catch (IOException e) {

			e.printStackTrace();
			Log.i("Hub", "IOException: " + e.toString());
		}
	}

	/**
	 * @category 保存到指定的路径
	 * @param bm
	 *            要保存的位图
	 * @param filePath
	 *            要保存的路径
	 * */
	private static void thumbAndSaveToPath(Bitmap bm, String filePath) {

		OutputStream outStream = null;
		File file = new File(filePath);
		try {
			outStream = new FileOutputStream(file);
			bm.compress(Bitmap.CompressFormat.JPEG, 100, outStream);
			outStream.flush();
			outStream.close();

			Log.i("Hub", "OK, Image Saved to Path");
			Log.i("Hub",
					"height = " + bm.getHeight() + ", width = " + bm.getWidth());

		} catch (FileNotFoundException e) {

			e.printStackTrace();
			Log.i("Hub", "FileNotFoundException: " + e.toString());

		} catch (IOException e) {

			e.printStackTrace();
			Log.i("Hub", "IOException: " + e.toString());
		}
	}

	public static String imageByteArrayToString64(byte[] source) {
		if (source == null) {
			return null;
		}
		String des = Base64.encodeToString(source, false);
		return des;
	}

	public static byte[] string64ToByteArray(String source) {
		if (source == null) {
			return null;
		}
		byte[] des = Base64.decode(source);
		return des;
	}

	/**
	 * 
	 * @param presence
	 * @param isConnected
	 * @return
	 */
//	public static int getNotificationIconResByPresence(String presence,
//			boolean isConnected) {
//		if (isConnected) {
//			if (presence.equals(IConstant.ONLINE)) {
//				return R.drawable.notification_overlay_online;
//			} else if (presence.equals(IConstant.OFFLINE)) {
//				return R.drawable.notification_overlay_offline;
//			} else if (presence.equals(IConstant.AWAY)) {
//				return R.drawable.notification_overlay_away;
//			} else if (presence.equals(IConstant.BUSY)) {
//				return R.drawable.notification_overlay_busy;
//			} else if (presence.equals(IConstant.XA)) {
//				return R.drawable.notification_overlay_idle;
//			} else if (presence.equals(IConstant.HIDE)) {
//				return R.drawable.notification_overlay_hide;
//			} else {
//				return R.drawable.notification_overlay_hide;
//			}
//		} else {
//			return R.drawable.notification_overlay_offline;
//		}
//	}

	/**
	 * OVERLAY THE RIGHTBOTTOMIMAGE OVER MAINIMAGE.
	 * 
	 * @param mainImage
	 *            should be lager than the right bottom one.
	 * @param rightBottomImage
	 * @param style
	 *            -
	 * @return
	 */
	public static Bitmap getOverlayedBitmapFromRes(Bitmap bitmap,
			Bitmap overlay, int style) {

		Canvas canvas = new Canvas(bitmap);
		Paint paint = new Paint(Paint.FILTER_BITMAP_FLAG);
		canvas.drawBitmap(overlay, bitmap.getWidth() - overlay.getWidth(),
				bitmap.getHeight() - overlay.getHeight(), paint);

		return bitmap;
	}

	/**
	 * For get resized bitmap byte array by the original bitmap.<br/>
	 * If the bitmap is from file, this function is not recommended to use. use
	 * the other function:
	 * {@link ImageUtilities#getByteArrayFromFileWithResizeOption(Bitmap, int, int, int)}
	 */
	public static byte[] getByteArrayFromBitmapWithResizeOption(
			Bitmap srcBitmap, int newWidth, int newHeight, int quality)
			throws IOException {

		Bitmap scaledBitmap = getResizedBitmapFromBitmap(srcBitmap, newWidth,
				newHeight);

		// BITMAP TO BYTE ARRAY
		byte[] data = bitmap2ByteArray(scaledBitmap, quality,
				Bitmap.CompressFormat.JPEG);

		return data;
	}

	/**
	 * 
	 * @param srcBitmap
	 * @param newWidth
	 * @param newHeight
	 * @param quality
	 * @return
	 * @throws IOException
	 */
	public static byte[] getByteArrayFromFileWithResizeOption(String filePath,
			int newWidth, int newHeight, int quality) throws IOException {

		Bitmap bitmap = ImageUtilities.getBitmapThumbnailFromFile(filePath,
				newWidth, newHeight);
		byte[] data = bitmap2ByteArray(bitmap, quality,
				Bitmap.CompressFormat.JPEG);
		return data;

	}

	/**
	 * 
	 * SCALE THE BITMAP TO A NEW ONE FIT THE NEW BORDERS.
	 * 
	 * @param originalBitmap
	 * @param newHeight
	 * @param newWidth
	 * @return the new Bitmap
	 */
	public static Bitmap getResizedBitmapFromBitmap(Bitmap originalBitmap,
			int newHeight, int newWidth) {
		int width = originalBitmap.getWidth();
		int height = originalBitmap.getHeight();
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		float bestScale = Math.min(scaleWidth, scaleHeight);

		// CREATE A MATRIX FOR THE MANIPULATION
		Matrix matrix = new Matrix();
		// RESIZE THE BIT MAP
		matrix.postScale(bestScale, bestScale);

		// RECREATE THE NEW BITMAP
		Bitmap resizedBitmap = Bitmap.createBitmap(originalBitmap, 0, 0, width,
				height, matrix, false);

		return resizedBitmap;

	}
	public static Bitmap getResizedBitmapFromBitmap2(Bitmap originalBitmap,
			int newHeight, int newWidth) {
		int width = originalBitmap.getWidth();
		int height = originalBitmap.getHeight();
		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		float bestScale = Math.min(scaleWidth, scaleHeight);

		// CREATE A MATRIX FOR THE MANIPULATION
		Matrix matrix = new Matrix();
		// RESIZE THE BIT MAP
		matrix.postScale(bestScale, bestScale);

		// RECREATE THE NEW BITMAP
		Bitmap resizedBitmap = Bitmap.createBitmap(originalBitmap, 0, 0, width,
				originalBitmap.getHeight(), matrix, false);

		return resizedBitmap;

	}

	public static Bitmap getRoundedRectBitmap(Bitmap bitmap) {
		int pixels = 6;
		int color;
		Paint paint;
		Rect rect;
		RectF rectF;
		Bitmap result;
		Canvas canvas;
		float roundPx;
		result = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(),
				Bitmap.Config.ARGB_8888);
		canvas = new Canvas(result);

		color = 0xff424242;
		paint = new Paint();
		rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		rectF = new RectF(rect);
		roundPx = pixels;

		paint.setAntiAlias(true);
		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, rect, rect, paint);

		return result;
	}

//	public static Bitmap getResizedBitmap(Bitmap bm, Context ctx) {
//		SharedPreferences sp = ctx.getSharedPreferences(
//				SettingKey.SHARED_PREFERENCE_NAME, Context.MODE_PRIVATE);
//		float size = sp.getFloat(SettingKey.CHAT_AVATAR_SIZE, 0);
//		if (bm != null) {
//			int width = bm.getWidth();
//			int height = bm.getHeight();
//			float scaleWidth = ((float) size) / width;
//			float scaleHeight = ((float) size) / height;
//			// CREATE A MATRIX FOR THE MANIPULATION
//			Matrix matrix = new Matrix();
//			// RESIZE THE BIT MAP
//			matrix.postScale(scaleWidth, scaleHeight);
//
//			// "RECREATE" THE NEW BITMAP
//			Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
//					matrix, false);
//			return resizedBitmap;
//		} else {
//			return null;
//		}
//	}

	public static Bitmap getResizedBitmapProfile(Bitmap bm, Context ctx) {

		float size = 70;
		if (bm != null) {
			int width = bm.getWidth();
			int height = bm.getHeight();
			float scaleWidth = ((float) size) / width;
			float scaleHeight = ((float) size) / height;
			// CREATE A MATRIX FOR THE MANIPULATION
			Matrix matrix = new Matrix();
			// RESIZE THE BIT MAP
			matrix.postScale(scaleWidth, scaleHeight);

			// "RECREATE" THE NEW BITMAP
			Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height,
					matrix, false);
			return resizedBitmap;
		} else {
			return null;
		}
	}

	public static Bitmap getResizedBitmapFeed(Bitmap bm) {
		try {
			float size = 60;
			if (bm != null) {
				int width = bm.getWidth();
				int height = bm.getHeight();
				float scaleWidth = ((float) size) / width;
				float scaleHeight = ((float) size) / height;
				// CREATE A MATRIX FOR THE MANIPULATION
				Matrix matrix = new Matrix();
				// RESIZE THE BIT MAP
				matrix.postScale(scaleWidth, scaleHeight);

				// "RECREATE" THE NEW BITMAP
				Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width,
						height, matrix, false);
				bm = null;
				return resizedBitmap;
			} else {
				return null;
			}
		} catch (OutOfMemoryError ex) {
			// We have no memory to rotate. Return the original bitmap.
			Log.e(TAG, "Got oom exception ", ex);
			return null;
		}
	}

	public static Bitmap getResizedBitmapFeed(Bitmap bm, int newWidth,
			int newHeight) {
		try {
			if (bm != null) {
				int width = bm.getWidth();
				int height = bm.getHeight();
				float scaleWidth = ((float) newWidth) / width;
				float scaleHeight = ((float) newHeight) / height;
				// CREATE A MATRIX FOR THE MANIPULATION
				Matrix matrix = new Matrix();
				// RESIZE THE BIT MAP
				matrix.postScale(scaleWidth, scaleHeight);

				// "RECREATE" THE NEW BITMAP
				Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width,
						height, matrix, false);
				bm = null;
				return resizedBitmap;
			} else {
				return null;
			}
		} catch (OutOfMemoryError ex) {
			// We have no memory to rotate. Return the original bitmap.
			Log.e(TAG, "Got oom exception ", ex);
			return null;
		}
	}
	
	public static Bitmap getResizedBitmapFeed(Bitmap bm, int newWidth) {
		try {
			if (bm != null) {
				int width = bm.getWidth();
				int height = bm.getHeight();
				float scale = ((float) newWidth) / width;
				// CREATE A MATRIX FOR THE MANIPULATION
				Matrix matrix = new Matrix();
				// RESIZE THE BIT MAP
				matrix.postScale(scale, scale);

				// "RECREATE" THE NEW BITMAP
				Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width,
						height, matrix, false);
				
				bm = null;
				System.gc();
				return resizedBitmap;
			} else {
				return null;
			}
		} catch (OutOfMemoryError ex) {
			// We have no memory to rotate. Return the original bitmap.
			Log.e(TAG, "Got oom exception ", ex);
			return bm;
		}
	}
	public static void fetchDrawableOnThread(final String urlString,
			final ImageView imageView, final Bitmap bitmap) {

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				if ((Drawable) message.obj != null) {
					imageView.setImageDrawable((Drawable) message.obj);
				} else {

					imageView.setImageBitmap(bitmap);
				}
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				// TODO : set imageView to a "pending" image
				Drawable drawable = fetchDrawable(urlString);
				if (drawable != null) {
					Message message = handler.obtainMessage(1, drawable);
					handler.sendMessage(message);
				}
			}
		};
		thread.start();
	}
	public static void fetchDrawableOnThread(final String urlString, final ImageView imageView, final int defaultResource) {

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				if ((Drawable) message.obj != null) {
					imageView.setImageDrawable((Drawable) message.obj);
				} else {
					imageView.setImageResource(defaultResource);
				}
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				// TODO : set imageView to a "pending" image
				Drawable drawable = fetchDrawable(urlString);
				if (drawable != null) {
					Message message = handler.obtainMessage(1, drawable);
					handler.sendMessage(message);
				}
			}
		};
		thread.start();
	}
	public static Drawable fetchDrawable(String urlString) {

		Drawable drawable = null;

		try {
			InputStream is = OpenHttpConnection(urlString);
			// Drawable drawable = Drawable.createFromStream(is, "src");
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;

			// decode with inSampleSize
			BitmapFactory.Options options2 = new BitmapFactory.Options();
			options2.inSampleSize = 1;

			if (is != null) {
				Bitmap preview_bitmap = BitmapFactory.decodeStream(is, null,
						options2);

				drawable = new BitmapDrawable(preview_bitmap);
				preview_bitmap = null;
			}

			return drawable;
		} catch (MalformedURLException e) {

			return null;
		} catch (IOException e) {

			return null;
		} catch (Exception e) {

			return null;
		} catch (Error err) {

			return null;
		}
	}
	
	private static InputStream OpenHttpConnection(String strURL)
			throws IOException {
		InputStream inputStream = null;
		URL url = new URL(strURL);
		URLConnection conn = url.openConnection();

		try {
			HttpURLConnection httpConn = (HttpURLConnection) conn;
			httpConn.setRequestMethod("GET");
			httpConn.connect();

			if (httpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
				inputStream = httpConn.getInputStream();
			}
		} catch (Exception ex) {
		}
		return inputStream;
	}
	
	public static Bitmap fetchBitmap(String urlString) {

		Bitmap preview_bitmap = null;

		try {
			InputStream is = OpenHttpConnection(urlString);
			// Drawable drawable = Drawable.createFromStream(is, "src");
			BitmapFactory.Options options = new BitmapFactory.Options();
			options.inJustDecodeBounds = true;

			// decode with inSampleSize
			BitmapFactory.Options options2 = new BitmapFactory.Options();
			options2.inSampleSize = 2;

			if (is != null) {
				 preview_bitmap = BitmapFactory.decodeStream(is, null,
						options2);
			}

			return preview_bitmap;
		} catch (MalformedURLException e) {

			return null;
		} catch (IOException e) {

			return null;
		} catch (Exception e) {

			return null;
		} catch (Error err) {

			return null;
		}
	}
	public static void fetchDrawableOnThreadPromotion(final String urlString,
			final ImageView imageView, final Bitmap bitmap) {

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				if ((Drawable) message.obj != null) {
					Bitmap bm = drawable2Bitmap((Drawable) message.obj);
//					imageView.setImageBitmap(toRoundCorner(bm,8));
					imageView.setImageBitmap(bm);
				} else {

					imageView.setImageBitmap(toRoundCorner(bitmap,8));
				}
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				// TODO : set imageView to a "pending" image
				Drawable drawable = fetchDrawable(urlString);
				if (drawable != null) {
					Message message = handler.obtainMessage(1, drawable);
					handler.sendMessage(message);
				}
			}
		};
		thread.start();
	}

	public static void fetchDrawableOnThreadPartner(final String urlString,
			final ImageView imageView, final Bitmap bitmap) {

		final Handler handler = new Handler() {
			@Override
			public void handleMessage(Message message) {
				if ((Drawable) message.obj != null) {
					imageView.setBackgroundDrawable((Drawable) message.obj);
				} else {

					imageView.setImageBitmap(bitmap);
				}
			}
		};

		Thread thread = new Thread() {
			@Override
			public void run() {
				// TODO : set imageView to a "pending" image
				Drawable drawable = fetchDrawable(urlString);
				if (drawable != null) {
					Message message = handler.obtainMessage(1, drawable);
					handler.sendMessage(message);
				}
			}
		};
		thread.start();
	}
//	
//	public static void fetchDrawableOnThreadImageProduct(final String urlString,
//			final ImageView imageView, final Bitmap bitmap,final ProgressBar pr) {
//
//		final Handler handler = new Handler() {
//			@Override
//			public void handleMessage(Message message) {
//				if ((Drawable) message.obj != null) {
//					Bitmap bm = drawable2Bitmap((Drawable) message.obj);
//					Bitmap newbmp = null;
//					if(bm.getWidth()<IM.screenWidth){
//						newbmp = ImageUtilities.getResizedBitmapFeed(bm, IM.screenWidth);
//						imageView.setImageBitmap(newbmp);
//						Log.d("New bitmap", ""+bm.getWidth()+":"+IM.screenWidth);
//					}else{
//						imageView.setImageBitmap(bm);
//					}
//
//					pr.setVisibility(View.GONE);
//				} 
//			}
//		};

//		Thread thread = new Thread() {
//			@Override
//			public void run() {
//				// TODO : set imageView to a "pending" image
//				Drawable drawable = fetchDrawable(urlString);
//				if (drawable != null) {
//					Message message = handler.obtainMessage(1, drawable);
//					handler.sendMessage(message);
//				}
//			}
//		};
//		thread.start();
//	}
}
